package com.example.common;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.config.converts.MySqlTypeConvert;
import com.baomidou.mybatisplus.generator.config.rules.DbColumnType;
import com.baomidou.mybatisplus.generator.config.rules.IColumnType;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;

import javax.sql.DataSource;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

/**
 * <p>
 *
 * </p>
 *
 * @author 12071
 * @date 2022/7/22 11:17
 */
public class MyCodeGenerator {

    /**
     * 数据源配置
     */
//    private static final DataSourceConfig.Builder DATA_SOURCE_CONFIG = new DataSourceConfig
//            .Builder("jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE;CASE_INSENSITIVE_IDENTIFIERS=TRUE;MODE=MYSQL", "sa", "");

    //排除生成的表 自定义
    private static final String[] excludeTable = new String[]{""};
    //需要生成的表 自定义
    private static final String[] includeTable = new String[]{"t_user", "t_role", "t_permission", "t_user_role", "t_role_permission"};
    //表名共同前缀
    private static final String TABLE_PREFIX = "t_";

    //包名
    private static final String PACKAGE_NAME = "com.example";
    //模块名称
    private static final String MODULE_NAME = "hello";

    //公共的子包名  跟下面的 control、dao、entity、service、service impl生成路径结合使用。配置时一定要"."开头
    private static final String COMMON_PATH = "";
    //private static final String COMMON_PATH = ".bs";

    //control层生成 存放路径  如：com.hm.dubbopractice.dubboserver.controller;
    private static final String CONTROLLER_PATH = "controller" + COMMON_PATH;

    //dao层生成 存放路径 如：com.hm.dubbopractice.dubboserver.dao;
    private static final String MAPPER_PATH = "mapper" + COMMON_PATH;
    private static final String MAPPER_XML_PATH = "mapper.xml" + COMMON_PATH;

    //entity bean对象生成 存放路径  如：com.hm.dubbopractice.dubboserver.entity;
    private static final String ENTITY_PATH = "entity" + COMMON_PATH;

    //service层代码生成存放路径  如：com.hm.dubbopractice.dubboserver.service;
    private static final String SERVICE_PATH = "service" + COMMON_PATH;

    //service impl层代码生成存放路径  如：com.hm.dubbopractice.dubboserver.service.impl;
    private static final String SERVICE_IMPL_PATH = SERVICE_PATH + ".impl";


    private static final String OUT_PATH = "D:\\";
    //代码生成者
    private static final String AUTHOR = "author";

    private static final Boolean IS_OVERRIDE = true;

    /**
     * JDBC相关配置
     */
    private static final String DRIVER = "com.mysql.cj.jdbc.Driver";
    //    private static final String DRIVER = "com.mysql.jdbc.Driver";
    private static final String URL = "jdbc:mysql://127.0.0.1:3306/db_shiro_test?useUnicode=true&characterEncoding=utf-8&connectTimeout=5000&socketTimeout=5000&useSSL=false&serverTimezone=GMT%2B8";
    private static final String USER_NAME = "root";
    private static final String PASSWORD = "root";

    public static void main(String[] args) {

        List<String> tables = Arrays.asList(includeTable);

        String[] xmlPaths = PACKAGE_NAME.split("\\.");
        StringBuilder xmlPath = new StringBuilder();
        for (String s : xmlPaths) {
            xmlPath.append(s).append("\\");
        }
        xmlPath.append(MODULE_NAME).append("\\");
        String finalXmlPath = xmlPath.toString();

        FastAutoGenerator
                .create(new DataSourceConfig.Builder(URL, USER_NAME, PASSWORD)
                        .typeConvert(new MySqlTypeConvert() {
                            // 自定义数据库表字段类型转换【可选】
                            @Override
                            public IColumnType processTypeConvert(GlobalConfig globalConfig, String fieldType) {
                                System.out.println("转换类型：" + fieldType);
                                if (fieldType.toLowerCase().contains("tinyint")) {
                                    System.out.println(String.format("%s -> %s", fieldType, DbColumnType.INTEGER));
                                    return DbColumnType.INTEGER;
                                }
                                if (fieldType.toLowerCase().contains("datetime")) {
                                    System.out.println(String.format("%s -> %s", fieldType, DbColumnType.DATE_SQL));
                                    return DbColumnType.DATE_SQL;
                                }
                                return super.processTypeConvert(globalConfig, fieldType);
                            }
                        }))
                .globalConfig(builder -> {
                    builder.author(AUTHOR) // 设置作者
                            .commentDate("yyyy-MM-dd")
                            .enableSwagger() // 开启 swagger 模式
                            .fileOverride() // 覆盖已生成文件
                            .outputDir(OUT_PATH); // 指定输出目录
                })
                .packageConfig(builder -> {
                    builder.parent(PACKAGE_NAME) // 设置父包名
                            .moduleName(MODULE_NAME) // 设置父包模块名
                            .entity(ENTITY_PATH)
                            .service(SERVICE_PATH)
                            .serviceImpl(SERVICE_IMPL_PATH)
                            .controller(CONTROLLER_PATH)
                            .mapper(MAPPER_PATH)
                            .xml(MAPPER_XML_PATH);
                            //.pathInfo(Collections.singletonMap(OutputFile.mapperXml, OUT_PATH + "\\" + finalXmlPath + MAPPER_PATH + "\\xml")); // 设置mapperXml生成路径
                })
                .strategyConfig(builder -> {
                    builder.addInclude(tables) // 设置需要生成的表名
                            .addTablePrefix(TABLE_PREFIX) // 设置过滤表前缀
                            .serviceBuilder()
                            .formatServiceFileName("%sService")
                            .formatServiceImplFileName("%sServiceImpl")
                            .entityBuilder()
                            .enableLombok()
                            .logicDeleteColumnName("deleted")
                            .enableTableFieldAnnotation()
                            .controllerBuilder()
                            .formatFileName("%sController")
                            .enableRestStyle()
                            .mapperBuilder()
                            .superClass(BaseMapper.class)
                            .formatMapperFileName("%sMapper")
                            .enableMapperAnnotation()
                            .formatXmlFileName("%sMapper");
                })
                .templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板，默认的是Velocity引擎模板
                .execute();
    }
}
